package com.nudge.portlet.api;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * This class handle the mapping of alert data into a NudgeAlert object.
 *
 * @author Frederic Massart
 */
public class MapNudgeAlert {

    /**
     * Class logger.
     */
    private final static Logger LOG = LoggerFactory.getLogger(MapNudgeAlert.class);


    // TODO externalise this with the sdf in MapNudgeData ?
    private final static SimpleDateFormat nudgeFormatDate = new SimpleDateFormat("yyyy-MM-dd HH:mm");


    /**
     * Create a NudgeAlert object from a CSV string coming from a nudge server response.
     *
     * @param alertCsv the data to parse and map, this string must respect 10 elements separated by a semicolon.
     *                 The order of element is : <br/>
     *                 0 - Alert id <br />
     *                 1 - Status <br />
     *                 2 - Description <br />
     *                 3 - Action <br />
     *                 4 - Server <br />
     *                 5 - User link <br />
     *                 6 - Start time <br />
     *                 7 - End time <br />
     *                 8 - Raised time <br />
     *                 9 - Closed time
     * @return the nudgeAlert object created
     */
    public NudgeAlert createNudgeAlert(final String alertCsv) {

        NudgeAlert nudgeAlert = new NudgeAlert();

        if (StringUtils.isEmpty(alertCsv)) {
            return nudgeAlert;
        }

        String[] alertElements = StringUtils.split(alertCsv, ";");

        if (alertElements.length != 10) {
            LOG.error("The data to parse in order to create a NudgeAlert object, does not respect the expected format");
        } else {
            // make all mappings
            mapAlertId(alertElements[0], nudgeAlert);
            mapStatus(alertElements[1], nudgeAlert);
            mapDescription(alertElements[2], nudgeAlert);
            mapAction(alertElements[3], nudgeAlert);
            mapServer(alertElements[4], nudgeAlert);
            mapUserLink(alertElements[5], nudgeAlert);
            try {
                mapStartTime(alertElements[6], nudgeAlert);
            } catch (ParseException pe) {
                LOG.error("The startTime is incorrect, the creation of a NudgeAlert object will not be complete", pe);
            }
            try {
                mapEndTime(alertElements[7], nudgeAlert);
            } catch (ParseException pe) {
                LOG.error("The endTime is incorrect, the creation of a NudgeAlert object will not be complete", pe);
            }
            try {
                mapRaisedTime(alertElements[8], nudgeAlert);
            } catch (ParseException pe) {
                LOG.error("The raisedTime is incorrect, the creation of a NudgeAlert object will not be complete", pe);
            }
            try {
                mapClosedTime(alertElements[9], nudgeAlert);
            } catch (ParseException pe) {
                LOG.error("The closedTime is incorrect, the creation of a NudgeAlert object will not be complete", pe);
            }
        }

        return nudgeAlert;
    }


    protected void mapAlertId(final String alertId, final NudgeAlert nudgeAlert) {

        if (StringUtils.isBlank(alertId)) {
            return;
        }
        try {
            nudgeAlert.setAlertId(Long.decode(alertId));
        } catch (NumberFormatException nfe) {
            LOG.error("Parsing of alertId failed, incorrect value '{} for a long", alertId);
        }
    }

    protected void mapStatus(final String status, final NudgeAlert nudgeAlert) {

        if (StringUtils.isBlank(status)) {
            return;
        }
        nudgeAlert.setStatus(status);
    }

    protected void mapDescription(final String description, final NudgeAlert nudgeAlert) {

        if (StringUtils.isBlank(description)) {
            return;
        }
        nudgeAlert.setDescription(description);
    }

    protected void mapAction(final String action, final NudgeAlert nudgeAlert) {

        if (StringUtils.isBlank(action)) {
            return;
        }
        nudgeAlert.setAction(action);
    }

    protected void mapServer(final String server, final NudgeAlert nudgeAlert) {

        if (StringUtils.isBlank(server)) {
            return;
        }
        nudgeAlert.setServer(server);
    }

    protected void mapUserLink(final String userLink, final NudgeAlert nudgeAlert) {

        if (StringUtils.isBlank(userLink)) {
            return;
        }
        nudgeAlert.setUserLink(userLink);
    }

    protected void mapStartTime(final String startTime, final NudgeAlert nudgeAlert) throws ParseException {

        if (StringUtils.isBlank(startTime)) {
            return;
        }
        Date date;
        try {
            date = nudgeFormatDate.parse(startTime);
        } catch (ParseException pe) {
            LOG.error("Parsing startTime failed, incorrect value '{}' for a date", startTime);
            throw pe;
        }
        nudgeAlert.setStartTime(date);

    }

    protected void mapEndTime(final String endTime, final NudgeAlert nudgeAlert) throws ParseException {

        if (StringUtils.isBlank(endTime)) {
            return;
        }
        Date date;
        try {
            date = nudgeFormatDate.parse(endTime);
        } catch (ParseException pe) {
            LOG.error("Parsing endTime failed, incorrect value '{}' for a date", endTime);
            throw pe;
        }
        nudgeAlert.setEndTime(date);
    }

    protected void mapRaisedTime(final String raisedTime, final NudgeAlert nudgeAlert) throws ParseException {

        if (StringUtils.isBlank(raisedTime)) {
            return;
        }
        Date date;
        try {
            date = nudgeFormatDate.parse(raisedTime);
        } catch (ParseException pe) {
            LOG.error("Parsing raisedTime failed, incorrect value '{}' for a date", raisedTime);
            throw pe;
        }
        nudgeAlert.setRaisedTime(date);
    }

    protected void mapClosedTime(final String closedTime, final NudgeAlert nudgeAlert) throws ParseException {

        if (StringUtils.isBlank(closedTime)) {
            return;
        }
        Date date;
        try {
            date = nudgeFormatDate.parse(closedTime);
        } catch (ParseException pe) {
            LOG.error("Parsing collectingDate failed, incorrect value '{}' for a date", closedTime);
            throw pe;
        }
        nudgeAlert.setClosedTime(date);
    }
}
